package immutablecollections;

import java.util.*;

/**
 * An iterator on an {@link ImTree}.
 * 
 * Because `ImTrees` are immutable, {@link #remove} will throw {@link UnsupportedOperationException}
 *
 */
class ImTreeIterator<T> implements Iterator<T>
{
    private ImMaybe<ImTreeZipper<T>> maybeNextPath;

    public ImTreeIterator(final ImTree<T> tree)
    {
        if (tree == ImTree.Nil())
            maybeNextPath = ImMaybe.nothing();
        else
            maybeNextPath = ImMaybe.with(ImTreeZipper.onLeftmost(tree));
    }

    public boolean hasNext()
    {
        return maybeNextPath.hasValue();
    }

    public T next()
    {
        if (!hasNext())
            throw new NoSuchElementException();

        ImTreeZipper<T> zipper = maybeNextPath.getValue();

        try
        {
            return zipper.getFocus().getElement();
        }
        finally
        {
            maybeNextPath = zipper.next();
        }
    }

    public void remove()
    {
        throw new UnsupportedOperationException();
    }
}
